/**
 * Skills Manager
 * 
 * Manages Claude Skills - reusable capabilities that can be attached to agents
 * Skills are higher-level abstractions built on top of tools
 */

import { logger } from '@/utils/logger';
import type { ToolDefinition } from '@/types';

/**
 * Skill definition
 */
export interface Skill {
  id: string;
  name: string;
  description: string;
  category: SkillCategory;
  version: string;
  author?: string;
  tools: ToolDefinition[];
  systemPrompt?: string;
  examples?: SkillExample[];
  metadata?: Record<string, any>;
}

/**
 * Skill categories
 */
export type SkillCategory =
  | 'data_analysis'
  | 'code_generation'
  | 'file_management'
  | 'web_scraping'
  | 'api_integration'
  | 'automation'
  | 'research'
  | 'creative'
  | 'custom';

/**
 * Skill example
 */
export interface SkillExample {
  title: string;
  description: string;
  input: string;
  expectedOutput?: string;
}

/**
 * Skills Manager
 * 
 * Manages registration, discovery, and activation of skills
 */
export class SkillsManager {
  private skills: Map<string, Skill> = new Map();
  private activeSkills: Set<string> = new Set();

  /**
   * Register a skill
   */
  registerSkill(skill: Skill): void {
    logger.info(`Registering skill: ${skill.name} (${skill.id})`);
    
    if (this.skills.has(skill.id)) {
      logger.warn(`Skill ${skill.id} already registered, overwriting`);
    }
    
    this.skills.set(skill.id, skill);
  }

  /**
   * Register multiple skills
   */
  registerSkills(skills: Skill[]): void {
    skills.forEach(skill => this.registerSkill(skill));
  }

  /**
   * Get a skill by ID
   */
  getSkill(id: string): Skill | undefined {
    return this.skills.get(id);
  }

  /**
   * Get all registered skills
   */
  getAllSkills(): Skill[] {
    return Array.from(this.skills.values());
  }

  /**
   * Get skills by category
   */
  getSkillsByCategory(category: SkillCategory): Skill[] {
    return this.getAllSkills().filter(skill => skill.category === category);
  }

  /**
   * Search skills by name or description
   */
  searchSkills(query: string): Skill[] {
    const lowerQuery = query.toLowerCase();
    return this.getAllSkills().filter(skill =>
      skill.name.toLowerCase().includes(lowerQuery) ||
      skill.description.toLowerCase().includes(lowerQuery)
    );
  }

  /**
   * Activate a skill
   */
  activateSkill(id: string): boolean {
    const skill = this.getSkill(id);
    if (!skill) {
      logger.error(`Cannot activate skill ${id}: not found`);
      return false;
    }
    
    this.activeSkills.add(id);
    logger.info(`Activated skill: ${skill.name}`);
    return true;
  }

  /**
   * Deactivate a skill
   */
  deactivateSkill(id: string): boolean {
    if (!this.activeSkills.has(id)) {
      return false;
    }
    
    this.activeSkills.delete(id);
    logger.info(`Deactivated skill: ${id}`);
    return true;
  }

  /**
   * Get all active skills
   */
  getActiveSkills(): Skill[] {
    return Array.from(this.activeSkills)
      .map(id => this.getSkill(id))
      .filter((skill): skill is Skill => skill !== undefined);
  }

  /**
   * Get all tools from active skills
   */
  getActiveTools(): ToolDefinition[] {
    const tools: ToolDefinition[] = [];
    
    this.getActiveSkills().forEach(skill => {
      tools.push(...skill.tools);
    });
    
    return tools;
  }

  /**
   * Get combined system prompt from active skills
   */
  getActiveSystemPrompt(): string {
    const prompts = this.getActiveSkills()
      .map(skill => skill.systemPrompt)
      .filter((prompt): prompt is string => !!prompt);
    
    if (prompts.length === 0) {
      return '';
    }
    
    return prompts.join('\n\n');
  }

  /**
   * Remove a skill
   */
  removeSkill(id: string): boolean {
    this.deactivateSkill(id);
    const removed = this.skills.delete(id);
    
    if (removed) {
      logger.info(`Removed skill: ${id}`);
    }
    
    return removed;
  }

  /**
   * Export skill configuration
   */
  exportSkill(id: string): string | null {
    const skill = this.getSkill(id);
    if (!skill) {
      return null;
    }
    
    return JSON.stringify(skill, null, 2);
  }

  /**
   * Import skill from configuration
   */
  importSkill(config: string): boolean {
    try {
      const skill = JSON.parse(config) as Skill;
      this.registerSkill(skill);
      return true;
    } catch (error) {
      logger.error('Failed to import skill', error);
      return false;
    }
  }

  /**
   * Get skill statistics
   */
  getStatistics() {
    const allSkills = this.getAllSkills();
    const categories = new Map<SkillCategory, number>();
    
    allSkills.forEach(skill => {
      categories.set(skill.category, (categories.get(skill.category) || 0) + 1);
    });
    
    return {
      total: allSkills.length,
      active: this.activeSkills.size,
      byCategory: Object.fromEntries(categories),
    };
  }
}

/**
 * Global skills manager instance
 */
export const skillsManager = new SkillsManager();

